/**
 * useTransition
 *
 *    概念：是一个让你在不阻塞 UI 的情况下来更新状态的 React Hook。
 *         在 18版本开始，React 新增了一种 过渡任务的概念，它是与立即更新任务（紧急任务）去做区别的。
 *         过渡任务是可以被暂停或中止的
 *
 *         页面中比如有一个 Tab 选项卡切换的效果，当点击某个 tab 时，这个 tab 需要高亮显示，这种高亮显示的任务就属于紧急任务，而选项卡切换的任务可以属于过渡任务
 *
 *    语法：
 *        const [pending, startTransition] = useTransition()
 *        1. pending - 是一个boolean值，用于表示当前过渡任务是否进行中
 *        2. startTransition - 是一个函数，在这个内部做的更新state的操作就会被标记为过渡任务
 */

import { useState, memo, useTransition } from "react";

function SlowPost({ index }) {
  let startTime = performance.now();
  while (performance.now() - startTime < 1) {
    // Do nothing for 1 ms per item to emulate extremely slow code
  }

  return <li className="item">Post #{index + 1}</li>;
}

// About 组件
function AboutTab() {
  return <p>Welcome to my profile!</p>;
}

// Posts 组件
const PostsTab = memo(function PostsTab() {
  // Log once. The actual slowdown is inside SlowPost.
  console.log("[ARTIFICIALLY SLOW] Rendering 1000 <SlowPost />");

  let items = [];
  for (let i = 0; i < 1000; i++) {
    items.push(<SlowPost key={i} index={i} />);
  }
  return <ul className="items">{items}</ul>;
});

function ContactTab() {
  return (
    <>
      <p>You can find me online here:</p>
      <ul>
        <li>admin@mysite.com</li>
        <li>+123456789</li>
      </ul>
    </>
  );
}

function TabButton({ children, isActive, onClick }) {
  const [isPending, startTransition] = useTransition();

  if (isActive) {
    return <b>{children}</b>;
  }

  if (isPending) {
    return <b className="pending">{children}</b>;
  }

  return (
    <button
      onClick={() => {
        startTransition(() => {
          // onClick 函数内同步代码的更新状态的任务就会被标记为过渡任务
          onClick();
        });
      }}
    >
      {children}
    </button>
  );
}

export default function App() {
  // tab 用于表示当前激活的 tab
  const [tab, setTab] = useState("about");

  // 选择某个 tab 触发
  function selectTab(nextTab) {
    // 更新状态的方法
    setTab(nextTab);

    // startTransition(() => {
    //   // 该状态更新，会被标记为 过渡任务
    //   setTab(nextTab);
    // });
  }

  return (
    <>
      <TabButton isActive={tab === "about"} onClick={() => selectTab("about")}>
        About
      </TabButton>
      <TabButton isActive={tab === "posts"} onClick={() => selectTab("posts")}>
        Posts (slow)
      </TabButton>
      <TabButton
        isActive={tab === "contact"}
        onClick={() => selectTab("contact")}
      >
        Contact
      </TabButton>
      <hr />
      {tab === "about" && <AboutTab />}
      {tab === "posts" && <PostsTab />}
      {tab === "contact" && <ContactTab />}
    </>
  );
}
